﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.IO;
using System.Transactions;
using DLM.Domain.DTO;
using DLM.Domain.Model;
using DLM.Domain.Repositories;
using DLM.Infrastructure.Authentication;
using DLM.Infrastructure.Domain;
using DLM.Infrastructure.Email;
using DLM.Infrastructure.Exception;
using DLM.Infrastructure.Security;
using DLM.Infrastructure.UnitOfWork;
using DLM.Services.BonusRule;
using DLM.Services.Interfaces;
using DLM.Infrastructure.Logging;

namespace DLM.Services.Implementations
{
    public class UserService : IUserService
    {

        private IUserRepository userRepository;
        private IAccountRepositroy accountRepository;
        private IFriendRepository friendRepository;
        private IFormsAuthentication formAuth;
        private IPhotoRepository photoRepository;
        private IUnitOfWork unitOfWork;
        private IEmailService emailService;
        private IBonusRepository bonusRepository;
        private IMessageRepository messageRepository;
        private INoticeRepository noticeRepository;
        private ISalutationRepository salutationRepository;
        private IBreakAppointmentRepository breakAppRepository;
        private IBonusLogRepository bonusLogRepository;
        private IUserViewRepository userViewRepository;

        public UserService(IUserRepository userRepository,
            IAccountRepositroy accountRepository,
            IUnitOfWork unitOfWork,
            IFormsAuthentication formAuth,
            IFriendRepository friendRepositroy,
            IPhotoRepository photoRepository,
            IEmailService emailService,
            IBonusRepository bonusRepository,
            IMessageRepository messageRepository,
            INoticeRepository noticeRepository,
            ISalutationRepository salutationRepository,
            IBreakAppointmentRepository breakAppRepository,
            IBonusLogRepository bonusLogRepository,
            IUserViewRepository userViewRepository)
        {
            this.userRepository = userRepository;
            this.accountRepository = accountRepository;
            this.unitOfWork = unitOfWork;
            this.formAuth = formAuth;
            this.friendRepository = friendRepositroy;
            this.photoRepository = photoRepository;
            this.emailService = emailService;
            this.bonusRepository = bonusRepository;
            this.messageRepository = messageRepository;
            this.noticeRepository = noticeRepository;
            this.salutationRepository = salutationRepository;
            this.breakAppRepository = breakAppRepository;
            this.bonusLogRepository = bonusLogRepository;
            this.userViewRepository = userViewRepository;
        }

        #region Account Service
        public void AddAccount(Account account)
        {
            if (account == null)
            {
                throw new ArgumentNullException("Item cannot be null!");
            }

            TransactionOptions transactionOption = new TransactionOptions();
            transactionOption.IsolationLevel = System.Transactions.IsolationLevel.ReadCommitted;
            using (TransactionScope transactionScope = new TransactionScope(TransactionScopeOption.Required, transactionOption))
            {
                try
                {
                    account.IsActive = false;
                    account.IsValidation = false;
                    account.ActiveCode = Guid.NewGuid().ToString();
                    account.CreateDate = DateTime.Now;
                    account.Password = Md5Encrypt.HashPassword(account.Password);

                    var user = account.Users.FirstOrDefault();
                    user.AccountName = account.AccountName;
                    user.CreateDate = DateTime.Now;
                    user.IsValidation = false;
                    user.Photo = "none_75_75.png";
                    this.accountRepository.Add(account);

                    Bonus bonus = new Bonus
                    {
                        Bonuses = 40,
                        CreateDate = DateTime.Now,
                        UpdateDate = DateTime.Now,
                        UserID = user.UserID
                    };
                    //  Initialize bonus
                    this.bonusRepository.Add(bonus);
                    // this.emailService.SendEmail(string.Empty, account.Email, "DLM Welcome", account.ActiveCode);
                    MailService ms = new MailService(this.emailService);
                    ms.SendRegisterNotice(account);
                    transactionScope.Complete();
                }
                catch (System.Net.Mail.SmtpException ec)
                {
                    LoggingFactory.GetLogger().Error(ec.Message, ec);
                    throw;
                }
                catch(Exception ex )
                {
                    LoggingFactory.GetLogger().Error(ex.Message, ex);
                    throw;
                }

               
            }
      
          
        }

        public void UpdateAccount(Account account)
        {
            if (account == null)
            {
                throw new ArgumentNullException("Item cannot be null!");
            }
            this.accountRepository.Save(account);
        }

        public void RemoveAccount(Account account)
        {
            if (account == null)
            {
                throw new ArgumentNullException("Item cannot be null!");
            }
            this.accountRepository.Remove(account);
        }

        public Account GetAccount(int accountID)
        {
            if (accountID < 0)
            {
                throw new ArgumentOutOfRangeException("Identity cannot be negative!");
            }
            return this.accountRepository.FindBy(accountID);
        }

        public Account GetAccount(string name)
        {
            if (string.IsNullOrEmpty(name))
            {
                throw new ArgumentNullException("Name cannot be null!");
            }
            return this.accountRepository.FindByName(name);
        }

        public IEnumerable<Account> GetAccount()
        {
            return this.accountRepository.FindAll();
        }

        public Account GetAccountByEmail(string email)
        {
            if (string.IsNullOrEmpty(email))
            {
                throw new ArgumentNullException("email");
            }
            return this.accountRepository.FindByEmail(email);
        }

        public IEnumerable<User> Participated(int partyID, int pageIndex, int pageSize)
        {
            if (partyID < 0)
            {
                throw new ArgumentOutOfRangeException("Id cannot be negative!");
            }
            return this.userRepository.FindByParticipated(partyID, pageIndex, pageSize);

        }

        public Account GetAccountByCode(string code)
        {
            if (string.IsNullOrEmpty(code))
            {
                throw new ArgumentNullException("code");
            }
            return this.accountRepository.FindByCode(code);
        }
        #endregion

        #region User Service
        public void AddUser(User user)
        {
            if (user == null)
            {
                throw new ArgumentNullException("User cannot be null!");
            }
            user.IsValidation = true;
            user.CreateDate = DateTime.Now;
            this.userRepository.Add(user);
        }

        public void UpdateUser(User user)
        {
            if (user == null)
            {
                throw new ArgumentNullException("User cannot be null!");
            }
            User currentUser = this.userRepository.FindBy(user.UserID);
            if(!string.IsNullOrEmpty(user.Photo))
            {
                string rootDir = System.Web.HttpContext.Current.Server.MapPath("~/Files/Photos/" + currentUser.UserID + "/");
                string dir = System.Web.HttpContext.Current.Server.MapPath("~/Files/Photos/" + currentUser.UserID + "/Title/");
                File.Delete(rootDir + currentUser.Photo);
                File.Delete(dir + currentUser.Photo);
                currentUser.Photo = user.Photo;
            }
            
            currentUser.Gender = user.Gender;
            currentUser.Marriage = user.Marriage;
            currentUser.Car = user.Car;
            currentUser.Age = user.Age;
            currentUser.Birthday = user.Birthday;
            currentUser.Education = user.Education;
            currentUser.HomePlace = user.HomePlace;
            currentUser.IM = user.IM;
            currentUser.Income = user.Income;
            currentUser.Industry = user.Industry;
            currentUser.Job = user.Job;
            currentUser.Location = user.Location;
            currentUser.Name = user.Name;
            currentUser.NativePlace = user.NativePlace;
            currentUser.Phone = user.Phone;
            currentUser.Position = user.Position;
            currentUser.Stature = user.Stature;
            currentUser.Weight = user.Weight;
            currentUser.Parents = user.Parents;
            currentUser.Introduction = user.Introduction;
            this.userRepository.Save(currentUser);
        }

        public void Remove(User user)
        {
            if (user == null)
            {
                throw new ArgumentNullException("User cannot be null!");
            }
            this.userRepository.Remove(user);
        }

        public User GetUser(int userID)
        {
            if (userID < 0)
            {
                throw new ArgumentOutOfRangeException("Id cannot be negative!");
            }
            // return this.userRepository.FindByAccount(userID);
            return this.userRepository.FindBy(userID);
        }

        public User GetUserByAccount(int accountID)
        {
            if (accountID < 0)
            {
                throw new ArgumentOutOfRangeException("Id cannot be negative!");
            }
            return this.userRepository.FindByAccount(accountID);
        }

        public User GetUser(string name)
        {
            if (string.IsNullOrEmpty(name))
            {
                throw new ArgumentNullException("Name cannot be null!");
            }
            return this.userRepository.FindByName(name);
        }

        public IEnumerable<User> GetUser()
        {
            return this.userRepository.FindAll();
        }

        public IEnumerable<User> SearchUser(string type, string parameter, int pageIndex, int pageSize)
        {
            if (string.IsNullOrEmpty(parameter))
            {
                throw new ArgumentNullException("Parameter");
            }
            IEnumerable<User> result;
            Nullable<bool> gender = null;
            if (!string.IsNullOrEmpty(parameter))
            {
                // gender = parameter.Contains("男") == true ? false : true;
                if (parameter.Contains("男"))
                {
                    gender = false;
                }
                else if( parameter.Contains("女"))
                {
                    gender = true;
                }
            }

            switch (type)
            {
                case "3":
                    result = this.userRepository.FindAll(u => u.Gender == gender.Value && u.IsValidation == true, pageIndex, pageSize);
                    break;
                case "1":
                    result = this.userRepository.FindAll(u => u.AccountName.Contains(parameter) && u.IsValidation == true, pageIndex, pageSize);
                    break;
                case "2":
                    result = this.userRepository.FindAll(u => u.NativePlace.Contains(parameter) && u.IsValidation == true, pageIndex, pageSize);
                    break;
                case "4":
                    int age = int.Parse(parameter);
                    result = this.userRepository.FindAll(u => u.Age == age && u.IsValidation == true, pageIndex, pageSize);
                    break;
                default:
                    result = this.userRepository.FindAll(u => (u.AccountName == parameter
                                || u.Gender == gender || u.NativePlace == parameter) && u.IsValidation == true, pageIndex, pageSize);
                    break;
            }
            return result;
        }
        #endregion

        #region Authorize
        public void Login(Account account)
        {
            if (account == null)
            {
                throw new ArgumentNullException("Account cannot be null!");
            }
            Account current = GetAccount(account.AccountName);
            if (current == null)
            {
                throw new System.Security.Authentication.InvalidCredentialException("Account is invalidate!");
            }
            if (!current.IsActive)
            {
                throw new System.Security.Authentication.AuthenticationException("Account is not active!");
            }
            if (!current.IsValidation)
            {
                throw new AccountNotValidateException("Account is not validate");
            }
            if (current.IsActive && current.IsValidation)
            {

                if (current.Password != Md5Encrypt.HashPassword(account.Password))
                {
                    throw new System.Security.Authentication.InvalidCredentialException("Password");
                }
                this.formAuth.SetAuthenticationToken(account.AccountName, "User");
            }
        }

        public void Activate(string code)
        {
            if (string.IsNullOrEmpty(code))
            {
                throw new ArgumentNullException("Code cannot be null!");
            }
            Account account = this.accountRepository.FindByCode(code);
            if (account == null)
            {
                throw new System.Security.Authentication.InvalidCredentialException("Active code is invalidae!");
            }
            if (account.IsActive)
            {
                return;
            }
            account.IsActive = true;
            account.IsValidation = true;
            var user = this.userRepository.FindByAccount(account.AccountID);
            user.IsValidation = true;
            this.accountRepository.Save(account);
            this.userRepository.Save(user);
        }

        public void LogOut()
        {
            this.formAuth.SignOut();
        }
        #endregion


        #region Friend Service
        public Friend FriendDetail(int friendID)
        {
            if (friendID < 0)
            {
                throw new ArgumentOutOfRangeException("Id cannot be negative!");
            }
            return this.friendRepository.FindBy(friendID);
        }

        public void AddFriend(string userName, int friendID)
        {
            if (friendID < 0)
            {
                throw new ArgumentOutOfRangeException("Id cannot be negative!");
            }

            User user = this.userRepository.FindByName(userName);
            var currentFriend = this.friendRepository.FindAll(f => f.MyFriendID == friendID && f.UserID == user.UserID);
            if (user.UserID == friendID)
            {
                throw new FriendExistException("请不要加自己好友");
            }
            if (currentFriend.Count() > 0)
            {
                throw new FriendExistException("该会员已经是您的好友");
            }
            Friend friend = new Friend
            {
                UserID = user.UserID,
                MyFriendID = friendID,
                CreateDate = DateTime.Now,
                IsConfirmed = false
            };
            this.friendRepository.Add(friend);


            Message message = new Message
            {
                CreateDate = DateTime.Now,
                Content = "会员" + userName + " 加您为好友,快去看看吧",
                Source = "好友",
                Title = "会员" + userName + "加您为好友",
                UserID = friendID
                
            };
            AddMessage(message);

        }

        public void ConfirmFriend(Friend friend)
        {
            if (friend == null)
            {
                throw new ArgumentNullException("Item cannot be null!");
            }
            Friend current = this.friendRepository.FindBy(friend.FriendID);
            if (!current.IsConfirmed)
            {
                current.IsConfirmed = true;

                this.friendRepository.Save(current);

                if (this.friendRepository.FindAll(fr => fr.UserID == current.MyFriendID && fr.MyFriendID == current.UserID.Value).Count() <= 0)
                {
                    Friend f = new Friend
                    {
                        UserID = current.MyFriendID,
                        MyFriendID = current.UserID.Value,
                        CreateDate = DateTime.Now,
                        IsConfirmed = true
                    };
                    this.friendRepository.Add(f);
                }


                Message systemMessage = new Message
                {
                    CreateDate = DateTime.Now,
                    Content = "您的好友请求被通过！",
                    Source = "好友",
                    Title = "好友请求通过",
                    UserID = current.UserID.Value
                };
                AddMessage(systemMessage);
            }
   
        }


        public IEnumerable<FriendDTO> FriendRequest(string userName, int pageIndex, int pageSize)
        {
            if (string.IsNullOrEmpty(userName))
            {
                throw new ArgumentNullException("Name cannot be null!");
            }
            return this.friendRepository.FindFriednRequest(userName, pageIndex, pageSize);
        }


        public IEnumerable<FriendDTO> MyFriend(string userName, int pageIndex, int pageSize)
        {
            if (string.IsNullOrEmpty(userName))
            {
                throw new ArgumentNullException("Name cannot be null!");
            }
            return this.friendRepository.FindMyFriend(userName, pageIndex, pageSize);
        }

        public IEnumerable<User> Friends(string accountName, int pageIndex, int pageSize)
        {
            if (string.IsNullOrEmpty(accountName))
            {
                throw new ArgumentNullException("Account name!");
            }
            return this.userRepository.FindMyFriend(accountName, pageIndex, pageSize);

        }

        public IEnumerable<Domain.DTO.FriendDTO> FriendHistory(string accountName, int pageIndex, int pageSize)
        {
            if (string.IsNullOrEmpty(accountName))
            {
                throw new ArgumentNullException("Account name");
            }
            return this.friendRepository.FindFriendDTO(accountName, pageIndex, pageSize);
        }
        #endregion




        #region Photo Service
        public void AddPhoto(Photo photo)
        {
            if (photo == null)
            {
                throw new ArgumentNullException("Item cannot be null!");
            }
            if (this.photoRepository.PhotoCount(photo.UserID) >= 4)
            {
                throw new PhotoEnoughException("Photo is enough");
            }
            this.photoRepository.Add(photo);
        }

        public void UpdatePhoto(Photo photo)
        {
            if (photo == null)
            {
                throw new ArgumentNullException("Item cannot be null!");
            }
            this.photoRepository.Save(photo);
        }

        public void RemovePhoto(int photoID)
        {
            if (photoID < 0)
            {
                throw new ArgumentOutOfRangeException("photo id");
            }


            var p = this.photoRepository.FindBy(photoID);
            if (p != null)
            {
               
                this.photoRepository.Remove(p);
                string parentDir = System.Web.HttpContext.Current.Server.MapPath("~/Files/Photos/" + p.UserID + "/Album/");
                string subDir = System.Web.HttpContext.Current.Server.MapPath("~/Files/Photos/" + p.UserID + "/Album/Thumb/");
                File.Delete(parentDir + p.Url);
                File.Delete(subDir + p.Url);

            }
            
        }

        public IEnumerable<Photo> GetPhotos(int userID)
        {
            if (userID < 0)
            {
                throw new ArgumentOutOfRangeException("Id cannot be negative!");
            }
            return this.photoRepository.FindAll(p => p.UserID == userID);
        }

        Photo IUserService.GetPhoto(int photoID)
        {
            if (photoID < 0)
            {
                throw new ArgumentOutOfRangeException("Id cannot be negative!");
            }
            return this.photoRepository.FindBy(photoID);
        }

        public bool HasPhoto(int userID)
        {
            return this.photoRepository.PhotoCount(userID) > 0 ? true : false;
        }
        #endregion



        public IEnumerable<Domain.DTO.BillBoard> ShowBillBoard()
        {

            var list = this.userRepository.BillBoard();
            return list;
        }



        public IEnumerable<User> GetUser(int pageIndex, int pageSize)
        {
            return this.userRepository.FindAll(pageIndex, pageSize);
        }


        #region Bonus Service
        public Bonus GetBonus(int userID)
        {
            if (userID < 0)
            {
                throw new ArgumentOutOfRangeException("User id");
            }
            return this.bonusRepository.FindBy(userID);

        }

        public void UpdateBonus(Bonus bonus)
        {
            if (bonus == null)
            {
                throw new ArgumentNullException("Bonus");
            }
            this.bonusRepository.Save(bonus);

        }

        public IEnumerable<Bonus> GetBonus(int pageIndex, int pageSize)
        {
            if (pageIndex < 0 || pageSize < 0)
            {
                throw new ArgumentOutOfRangeException("Page index");
            }
            return this.bonusRepository.FindAll(pageIndex, pageSize);
        }
        #endregion


        #region Message Service
        public Message GetMessage(int messageID)
        {
            if (messageID < 0)
            {
                throw new ArgumentOutOfRangeException("Message id");
            }
            return this.messageRepository.FindBy(messageID);
        }

        public IEnumerable<Message> GetMessage(string accountName, int pageIndex, int pageSize)
        {
            if (string.IsNullOrEmpty(accountName))
            {
                throw new ArgumentNullException("Account name");
            }
            return this.messageRepository.FindByUser(accountName, pageIndex, pageSize);
        }

        public void DeleteMessage(int messageID)
        {
            if (messageID < 0)
            {
                throw new ArgumentOutOfRangeException("Message id");
            }
            Message message = this.messageRepository.FindBy(messageID);
            this.messageRepository.Remove(message);
        }

        public void AddMessage(Message message)
        {
            if (message == null)
            {
                throw new ArgumentNullException("Message");
            }
            message.CreateDate = DateTime.Now;
            this.messageRepository.Add(message);
        }

        public void ConfirmeMessage(int id)
        {
            var message = this.messageRepository.FindBy(id);
            message.IsRead = true;
            this.messageRepository.Save(message);

        }
        #endregion

        public void SetBlack(int userID, int accountID)
        {
            var user = this.userRepository.FindBy(userID);
            user.IsValidation = false;
            var account = this.accountRepository.FindBy(accountID);
            account.IsActive = true;
            account.IsValidation = false;
            this.userRepository.Save(user);
            this.accountRepository.Save(account);

        }


        public IEnumerable<User> GetBlackList(int pageIndex, int pageSize)
        {
            if (pageIndex < 0 || pageSize < 0)
            {
                throw new ArgumentOutOfRangeException("Page index");
            }
            return this.userRepository.FindAll(u => u.IsValidation == false, pageIndex, pageSize);
        }

        public IEnumerable<User> GetValidateUser(int pageIndex, int pageSize)
        {
            if (pageIndex < 0 || pageSize < 0)
            {
                throw new ArgumentOutOfRangeException("Page index");
            }
            return this.userRepository.FindAll(u => u.IsValidation == true, pageIndex, pageSize);
        }

        #region Notice Service
        public void AddNotice(Notice notice)
        {
            if (notice == null)
            {
                throw new ArgumentNullException("Notice");
            }
            this.noticeRepository.Add(notice);
        }

        public void UpdateNotice(Notice notice)
        {
            if (notice == null)
            {
                throw new ArgumentNullException("Notice");
            }
            this.noticeRepository.Save(notice);
        }

        public void RemoveNotice(Notice notice)
        {
            if (notice == null)
            {
                throw new ArgumentNullException("Notice");
            }
            this.noticeRepository.Remove(notice);
        }

        public IEnumerable<Notice> GetNotice(int pageIndex, int pageSize)
        {
            return this.noticeRepository.FindAll(pageIndex, pageSize);
        }

        public Notice GetNotice(int noticeID)
        {
            if (noticeID < 0)
            {
                throw new ArgumentOutOfRangeException("Notice id");
            }
            return this.noticeRepository.FindBy(noticeID);
        }
        #endregion






        #region Salutation Service
        public void AddGreet(string userName, int greetID, int type, string message)
        {

            if (greetID <= 0)
            {
                throw new ArgumentOutOfRangeException("Greet id");
            }

            var bonus = this.bonusRepository.FindByUser(greetID);
            if (bonus != null)
            {
                if (bonus.Bonuses.Value <= 1)
                {

                    throw new DLM.Infrastructure.Exception.BounsNotEnoughException("积分不足，请充值");
                }
            }
            var user = this.userRepository.FindByName(userName);
            var greet = this.salutationRepository.FindAll(s => s.GreetID == greetID && s.UserID == user.UserID);
            if (user.UserID == greetID)
            {
                throw new SalutationExistException("请不要给自己打招呼");
            }
            if (greet.Count() > 0)
            {
                throw new SalutationExistException("你已经打过招呼了");
            }
            Salutation salutation = new Salutation
            {
                Type = type,
                IsConfirm = false,
                UserID = user.UserID,
                GreetID = greetID,
                Message = message,
                SentDate = DateTime.Now,
            };
            this.salutationRepository.Add(salutation);

            Message systemMessage = new Message
            {
                CreateDate = DateTime.Now,
                Content = "会员 " + userName + " 向您打招呼,快去看看吧",
                Source = "打招呼",
                Title = userName + "的招呼",
                UserID = greetID
            };
            AddMessage(systemMessage);
        }

        public void UpdateGreet(int id)
        {
            if (id <= 0)
            {
                throw new ArgumentOutOfRangeException("id");
            }
            var salutation = this.salutationRepository.FindBy(id);
            if (!salutation.IsConfirm)
            {
                salutation.IsConfirm = true;
                this.salutationRepository.Save(salutation);

                Message systemMessage = new Message
                {
                    CreateDate = DateTime.Now,
                    Content = "您的招呼已被响应",
                    Source = "打招呼",
                    Title = "招呼响应",
                    UserID = salutation.UserID
                };
               
                
                AddMessage(systemMessage);


                var bonus = this.bonusRepository.FindByUser(salutation.UserID);
                if (bonus != null)
                {
                    if (bonus.Bonuses.Value <= 1)
                    {
                        throw new DLM.Infrastructure.Exception.BounsNotEnoughException("积分不足，请充值");
                    }

                    if (salutation.Type == (int)GreetType.Phone)
                    {
                        bonus.Bonuses = bonus.Bonuses + BonusRuleFactory.GetBonusRuleService().Phone;
                    }
                    else
                    {
                        bonus.Bonuses = bonus.Bonuses + BonusRuleFactory.GetBonusRuleService().Salutation;
                    }
                    bonus.UpdateDate = DateTime.Now;
                    this.bonusRepository.Save(bonus);
                }
                else
                {
                    Bonus b = new Bonus
                    {

                        CreateDate = DateTime.Now,
                        UpdateDate = DateTime.Now,
                        UserID = salutation.UserID
                    };
                    if (salutation.Type == (int)GreetType.Phone)
                    {
                        b.Bonuses = BonusRuleFactory.GetBonusRuleService().Phone;
                    }
                    else
                    {
                        b.Bonuses = BonusRuleFactory.GetBonusRuleService().Salutation;
                    }
                    this.bonusRepository.Add(b);
                }
                // Add bonus log
                BonusLog log = new BonusLog
                {
                    CreateDate = DateTime.Now,
                    PartyID = 0,
                    UserID = salutation.UserID,
                    Desc = "打招呼所扣积分"
                };
                if (salutation.Type == (int)GreetType.Phone)
                {
                    log.Bonus = BonusRuleFactory.GetBonusRuleService().Phone;
                }
                else
                {
                    log.Bonus =  BonusRuleFactory.GetBonusRuleService().Salutation;
                }
                this.bonusLogRepository.Add(log);
            }
  

        }

        public void RemoveGreet(int greetID)
        {
            if (greetID < 0)
            {
                throw new ArgumentOutOfRangeException("Greet");
            }
            var salutation = this.salutationRepository.FindBy(greetID);
            this.salutationRepository.Remove(salutation);
        }

        public IEnumerable<SalutationDTO> GetMyGreet(string accountName, int pageIndex, int pageSize)
        {
            if (string.IsNullOrEmpty(accountName))
            {
                throw new ArgumentNullException("Account name");
            }
            return this.salutationRepository.FindMyGreet(accountName, pageIndex, pageSize);
        }

        public IEnumerable<SalutationDTO> GetGreetHistory(string accountName, int pageIndex, int pageSize)
        {
            if (string.IsNullOrEmpty(accountName))
            {
                throw new ArgumentNullException("Account name");
            }
            return this.salutationRepository.FindSalutationByAccount(accountName, pageIndex, pageSize);
        }

        public IEnumerable<SalutationDTO> GetAgreedGreet(string accountName, int pageIndex, int pageSize)
        {
            if (string.IsNullOrEmpty(accountName))
            {
                throw new ArgumentNullException("Account name");
            }
            return this.salutationRepository.FindConfirmedSalutationByAccount(accountName, pageIndex, pageSize);
        }
        #endregion


        #region Break App Service
        public void AddAppointment(int userID, int partyID)
        {
            if (userID < 0 || partyID < 0)
            {
                throw new ArgumentNullException("Id");
            }
            var list = this.breakAppRepository.FindAll(b => b.UserID == userID && partyID == partyID);
            if (list != null && list.Count() >0)
            {
                throw new ArgumentNullException("已针对该会员执行了爽约操作");
            }
            BreakAppointment app = new BreakAppointment
            {
                PartyID = partyID,
                UserID = userID,
                CreateDate = DateTime.Now
            };

            var bonus = this.bonusRepository.FindByUser(userID);
            if (bonus != null)
            {
                bonus.Bonuses = 
                    (bonus.Bonuses.Value - BonusRuleFactory.GetBonusRuleService().TemporaryDistrain)
                    + BonusRuleFactory.GetBonusRuleService().Quit.BreakAnAppointment;
            }
            BonusLog log = new BonusLog
            {
                Bonus = BonusRuleFactory.GetBonusRuleService().Quit.BreakAnAppointment,
                CreateDate = DateTime.Now,
                PartyID = partyID,
                UserID = userID,
                Desc = "爽约积分扣除"
            };
            this.breakAppRepository.Add(app);
            this.bonusLogRepository.Add(log);
        }

        public void UpdateAppointment(int pid, int userID, int partyID)
        {
            if (userID < 0 || partyID < 0)
            {
                throw new ArgumentNullException("Id");
            }
            var app = this.breakAppRepository.FindBy(pid);
            app.UserID = userID;
            app.PartyID = partyID;
            this.breakAppRepository.Save(app);
        }

        public void RemoveAppointment(int bid)
        {
            if (bid < 0)
            {
                throw new ArgumentNullException("Id");
            }
            var app = this.breakAppRepository.FindBy(bid);
            this.breakAppRepository.Remove(app);
        }

        public IEnumerable<BreakAppointment> GetBreakAppByUser(int userID, int pageIndex, int pageSize)
        {
            if (userID < 0)
            {
                throw new ArgumentNullException("User id");
            }
            return this.breakAppRepository.FindAll(a => a.UserID == userID, pageIndex, pageSize);
        }

        public IEnumerable<BreakAppointment> GetBreakAppByParty(int partyID, int pageIndex, int pageSize)
        {
            if (partyID < 0)
            {
                throw new ArgumentNullException("User id");
            }
            return this.breakAppRepository.FindAll(a => a.PartyID == partyID, pageIndex, pageSize);
        }
        #endregion



        public void ActiveUser(int userID)
        {
            if (userID < 0)
            {
                throw new ArgumentNullException("user id");
            }
            var user = this.userRepository.FindBy(userID);
            if (user != null)
            {
                user.IsValidation = true;
                var account = this.accountRepository.FindBy(user.AccountID);
                account.IsActive = true;
                account.IsValidation = true;
                this.userRepository.Save(user);
                this.accountRepository.Save(account);

            }


        }


        public IEnumerable<BonusDTO> GetBonusDTO(int pageIndex, int pageSize)
        {
            return this.bonusRepository.FindBonusDTO(pageIndex, pageSize);
        }


        public void UpdateBonus(IList<Bonus> list)
        {
            if (list == null)
            {
                throw new ArgumentNullException("list");
            }
            this.bonusRepository.BachUpdate(list);
        }


        public void AddView(int userID, string browserIP)
        {
            if (userID < 0)
            {
                throw new ArgumentOutOfRangeException("user id");
            }
            UserView view = new UserView
            {
                 UserID = userID,
                 IP= browserIP,
                 ViewDate = DateTime.Now
            };
            this.userViewRepository.Add(view);
            
        }

        public bool IsGreeted(string accountName, int greetID)
        {
            if (string.IsNullOrEmpty(accountName))
            {
                throw new ArgumentNullException("Account");
            }
            return this.salutationRepository.IsGreeted(accountName, greetID);
        }

        public IEnumerable<User> GetUser(DateTime begDate, DateTime endDate)
        {
            return this.userRepository.FindAll(u=>u.CreateDate >= begDate && u.CreateDate <= endDate);
        }
    }
}
